package org.jgs1904.filter;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.Map;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.io.IOUtils;
import org.jgs1904.bean.LoginFilterExcept;
import org.jgs1904.entity.User;

import com.alibaba.fastjson.JSON;

/**
 * 登录过滤器
 * 
 * @author junki
 * @date 2020年3月27日
 */
public class LoginFilter implements Filter {

	private LoginFilterExcept loginFilterExcept = null;
	
	private String loginPage = "";

	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {

		HttpServletRequest httpRequest = (HttpServletRequest) request;
		HttpServletResponse httpResponse = (HttpServletResponse) response;

		// 判断是否有需要排除的页面或者路径
		if (loginFilterExcept != null) {
			// 如果本次请求已被排除，直接放行
			if (!checkUrl(httpRequest)) {
				chain.doFilter(request, response);
				return;
			}
		}

		// 从session中获取在线用户
		User onlineUser = (User) httpRequest.getSession().getAttribute("onlineUser");

		// 判断在线用户是否为空
		if (onlineUser == null) {
			System.out.println("拦截请求：" + httpRequest.getRequestURL().toString());
			httpResponse.sendRedirect(httpRequest.getContextPath() + loginPage);
			return;
		}

		// 有在线用户直接放行
		chain.doFilter(request, response);
	}

	/**
	 * 	判断是否拦截url地址
	 * @param httpRequest
	 * @return true表示拦截、false不拦截
	 */
	private boolean checkUrl(HttpServletRequest httpRequest) {
		String url = httpRequest.getRequestURL().toString();
		List<String> pages = loginFilterExcept.getPages();
		Map<String, List<String>> methods = loginFilterExcept.getMethods();
		List<String> paths = loginFilterExcept.getPaths();

		// 判断不拦截的页面
		if (pages != null) {
			for (String page : pages) {
				if (url.endsWith(page)) {
					return false;
				}
			}
		}

		// 判断不拦截的method
		if (methods != null) {
			String controllerPath = url.substring(url.lastIndexOf("/"));
			if (methods.containsKey(controllerPath)) {
				String method = httpRequest.getParameter("method");
				List<String> methodList = methods.get(controllerPath);
				if (methodList.contains(method)) {
					return false;
				}
			}
		}

		// 判断不拦截的路径
		if (paths != null) {
			for (String path : paths) {
				if (url.contains(path)) {
					return false;
				}
			}
		}
		return true;
	}

	public void init(FilterConfig fConfig) throws ServletException {
		loginPage = fConfig.getInitParameter("loginPage");
		
		String except = fConfig.getInitParameter("except");
		InputStream is = this.getClass().getClassLoader().getResourceAsStream(except);
		if (except != null) {
			try {
				loginFilterExcept = JSON.parseObject(IOUtils.toString(is, "utf-8"), LoginFilterExcept.class);
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	public void destroy() {

	}

}
